/**
 * 
 */
package net.sf.cldsql.dyna.main;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.SQLException;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.sf.cldsql.dj.db.ConnPool;
import net.sf.cldsql.dj.db.DbConnection;
import net.sf.cldsql.dj.mvc.DiContextServletImpl;
import net.sf.cldsql.dj.mvc.DiServlet;
import net.sf.cldsql.dj.utl.DiException;
import net.sf.cldsql.dyna.utl.DynaContext;
import net.sf.cldsql.dyna.utl.ServletHlpr;

/**
 * DataServlet
 */
public class DynaServlet extends DiServlet {
    
    final Logger log = LoggerFactory.getLogger(DynaServlet.class);
    
    /** serial */
    private static final long serialVersionUID = 1L;
    
    /** constructor */
    public DynaServlet() {
    }
    
    /** init */
    public void init () {
        log.info("Servlet init begin.");
        ServletHlpr hlpr = new ServletHlpr(this);
        //HashMap<String, ConnPool> poolMap = hlpr.getConnPoolMap();
        log.info("Servlet init end.");
    }
    
    protected void service(final HttpServletRequest req, final HttpServletResponse res) {
        try {
            long beginTs = System.currentTimeMillis();
            log.info("Servlet request begin.");
            
            final DynaContext context = new DynaContext(req, res, this);
            ServletHlpr hlpr = new ServletHlpr(context);
            hlpr.initRequestAttribute();
            
            if (context.getRequest().getCharacterEncoding() == null) {
                context.getResponse().setCharacterEncoding("UTF-8");
            }

            if(context.getRequest().getProtocol().equals("HTTP/1.0")) {
                context.getResponse().setHeader("Pragma","no-cache");
            } else if(context.getRequest().getProtocol().equals("HTTP/1.1")) {
                context.getResponse().setHeader("Cache-Control","no-cache");
            }
            context.getResponse().setDateHeader("Expires",0);
            context.getResponse().setCharacterEncoding("UTF-8");

            String path = context.getPathInfo();
            String contextReal = this.getServletContext().getRealPath("/");
            
            if (path.endsWith(".html") 
                    || path.endsWith(".jsp")) {
                context.getResponse().setContentType("text/html");
            } else if (path.endsWith(".js") 
                    || path.endsWith(".ajax")) {
                context.getResponse().setContentType("text/javascript");
            } else if (path.endsWith(".xml")) {
                context.getResponse().setContentType("text/xml");
            } else if (path.endsWith(".css")) {
                context.getResponse().setContentType("text/css");
            } else if (path.endsWith(".txt")) {
                context.getResponse().setContentType("text/plain");
            } else {
                context.getResponse().setContentType("text/html");
            }

            try {
                if (path.equals("/")) {
                    res.sendError(404);
                } else if (path.equals("/_manage")) {
                    String action = context.getParam("action");
                    if (action == null) {
                        context.include("/WEB-INF/jsp/manage.jsp");
                    } else if (action.equals("load")) {
                        String pageSource = load(contextReal, "/WEB-INF/dyna/", context.getParam("name"));
                        context.getResponse().setContentType("text/plain");
                        context.getResponse().getWriter().write(pageSource);
                    } else if (action.equals("save")) {
                        context.getResponse().setContentType("text/javascript");
                        save(contextReal, "/WEB-INF/dyna/", context.getParam("name"), context.getParam("pageSource"));
                        context.getResponse().getWriter().write("{\"status\":\"ok\"}");
                    }
                } else {
                    context.include("/WEB-INF/dyna/" + path + ".jsp");
                }
                context.commitConns();
            } catch (Throwable t) {
                context.rollbackConns();
                throw new DiException (t);
            } finally {
                context.releaseConns();
            }
            
            
            long endTs = System.currentTimeMillis();
            log.info("Servlet request finished in {} ms.", endTs - beginTs);
        } catch (Exception e) {
            throw new DiException(e);
        }
    }

    /**
     * @param pageSource 
     * @param string 
     * @param string
     * @param param
     * @throws IOException 
     */
    private void save(String contextReal, String path, String name, String pageSource) throws IOException {

        String dirName = contextReal + "/" + path;
        new File(dirName).mkdirs();
        OutputStreamWriter out = new OutputStreamWriter (new FileOutputStream(dirName + "/" + name + ".jsp"), "UTF-8");
        out.write(pageSource);
        out.close();

        String containerName = new File(contextReal).getName();
        dirName = contextReal + "../../work/dyna/" + containerName + "/" + path;
        dirName = new File(dirName).getAbsolutePath();
        new File(dirName).mkdirs();
        out = new OutputStreamWriter (new FileOutputStream(dirName + "/" + name + ".jsp"), "UTF-8");
        out.write(pageSource);
        out.close();
        
        /*
        FileOutputStream tmpOut = new FileOutputStream(contextReal + path + name + ".jsp");
        tmpOut.write(pageSource.getBytes());
        */

    }

    /**
     * @param string 
     * @param string
     * @param param
     * @throws IOException 
     */
    private String load(String contextReal, String path, String name) throws IOException {
        File file = new File(contextReal + path + name + ".jsp");
        if (!file.exists()) {
            String containerName = new File(contextReal).getName();
            String dirName = contextReal + "../../work/dyna/" + containerName + "/" + path;
            dirName = new File(dirName).getAbsolutePath();
            file = new File(dirName + "/" + name + ".jsp");
            if (!file.exists()) {
                throw new DiException("file not found");
            }
        }
        FileInputStream fis = new FileInputStream(file);
        byte[] data = new byte[(int)file.length()];
        fis.read(data);
        fis.close();
        String s = new String(data, "UTF-8");
        return s;
    }

}
